package icrts.display;

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.util.HashSet;
import icrts.logic.*;
import icrts.*;
import java.util.Iterator;
import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;

// jpanel that implements the game map
public class MapPanel extends JPanel implements ActionListener{

	private int initX;
	private int initY;
	private int currentX;
	private int currentY;
	private boolean released;
	private boolean dragged;
	private int dragBoxX;
	private int dragBoxY;
	private int dragBoxHeight;
	private int dragBoxWidth;

	// sets to store the current game state and the selected units
	private HashSet<AbstractGameObject> gameState;
	private HashSet<AbstractGameObject> selectedUnits;

	// the bgColor of the the map panel
	private Color bgColor = Color.BLACK;

	// the default popup menu for constructing building
	private JPopupMenu defaultPopupMenu;
		
	public MapPanel(){

		setBorder(BorderFactory.createLineBorder(Color.WHITE));
		setBackground(bgColor);

		selectedUnits = new HashSet<AbstractGameObject>();

		initPopupMenu();

		// add listeners for mouseClicked, mousePressed & mouseReleased events
		addMouseListener( new MouseAdapter(){

			public void mouseClicked(MouseEvent e){

				

				initX = e.getX();
				initY = e.getY();

				if (e.getButton() == 1){

                    if ( selectedUnits.size() > 0 ){
                        
                        AbstractGameObject current = null;

                        Iterator<AbstractGameObject> it =
                                    selectedUnits.iterator();

                        while ( it.hasNext() ){
                              	current = it.next();
                        	  	System.out.println("Move at " +initX + " " + initY );
                                ((SampleRangedUnit)current).moveThis(initX, initY, 20);
                            
                        }

                    }
                    else {
                        selectedUnits.clear();

                        AbstractGameObject current = null;

                        Iterator<AbstractGameObject> it = gameState.iterator();
	
                        while ( it.hasNext() ){
                            current = it.next();
                            if ( current.selects(initX, initY) ) {
                                current.printID();
                                selectedUnits.add(current);
                            break;
                            }
                        }
               
                    }
				} else 
				if (e.getButton() == 3 ){
					//TestGameManager.createNewBuilding(x, y);
					defaultPopupMenu.show(e.getComponent(), e.getX(), e.getY() );
				}

				repaint();

			}

			public void mousePressed(MouseEvent e){
				initX = e.getX();
				initY = e.getY();	
				released = false;

				selectedUnits.clear();
				
			}
		
			public void mouseReleased(MouseEvent e){
				released = true;	
				if (dragBoxWidth != 0 && dragBoxHeight != 0){
					getSelectedUnits(dragBoxX, dragBoxY, dragBoxWidth,  dragBoxHeight);				
				}
				repaint();

			}
		});


		// adds listener for the mouse dragged event
		addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e){
			//	repaint(dragBoxX, dragBoxY, dragBoxWidth, dragBoxHeight);
				currentX = e.getX();
				currentY = e.getY();

				updateDragBox();
			//	repaint(dragBoxX, dragBoxY, dragBoxWidth, dragBoxHeight);		
				repaint();
			}
		});
	}

	public Dimension getPreferredSize(){
		return new Dimension(250,200);
	}

	public void paintComponent(Graphics g){
		super.paintComponent(g);
		
		getGameState();

		drawGameObjects(g);

		drawDragBox(g);

	}


	// draws all the game objects
	private void drawGameObjects(Graphics g){

		Iterator<AbstractGameObject> it = gameState.iterator();
		AbstractGameObject current;

		while ( it.hasNext() ){
			current = it.next();
			current.draw(g, false);
		}

		Iterator<AbstractGameObject> itS = selectedUnits.iterator();
		while ( itS.hasNext() ){
			itS.next().draw(g, true);
		}
		
	}

	// obtains the current game state (currently from the TestGameManager)
	private void getGameState(){
		gameState = GameManager.getGameState();
	}


	// determines the units selected through the use of the drag box
	// and stores them in selectedUnits 
	private void getSelectedUnits(int x, int y, int width, int height){

		AbstractGameObject current = null;
		selectedUnits.clear();
		boolean selected;

		Iterator<AbstractGameObject> it = gameState.iterator();

		while ( it.hasNext() ){
			current = it.next();
			selected = false;
			for (int i = x; i< x + width && !selected; i++ )
				for (int j = y; j<y + height && !selected; j++)

					if ( current.selects(i, j) ) {
						current.printID();
						selectedUnits.add(current);
						selected = true;
					}
				
			}

	
	}

	// updates the coordinates of the dragBox
	private void updateDragBox(){
                dragBoxX = (currentX < initX? currentX : initX);
				dragBoxY = (currentY < initY? currentY : initY);
				dragBoxHeight = Math.abs(currentY - initY);
				dragBoxWidth  = Math.abs(currentX - initX);
	}

	// draws the drag box on the jpanel
	public void drawDragBox(Graphics g){

		g.setColor(Color.GREEN);
		if ( !released )
			g.drawRect(dragBoxX, dragBoxY, dragBoxWidth, dragBoxHeight);
		
	}

	private void initPopupMenu(){
		defaultPopupMenu = new JPopupMenu();

		JMenuItem buildSampleBuilding = new JMenuItem("Build SampleBuilding");
		buildSampleBuilding.addActionListener(this);

		defaultPopupMenu.add(buildSampleBuilding);
		
		
	}

	public void actionPerformed(ActionEvent e){
		GameManager.createNewBuilding(initX, initY);
	}

    public void update(){
        repaint();
    }

}


